!** Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
!** See https://llvm.org/LICENSE.txt for license information.
!** SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

!* Tests for runtime library MATMUL routines

program p
    use check_mod
    implicit none
    real(kind=16), dimension(10, 11) :: arr1
    real(kind=16), dimension(11) :: arr2
    real(kind=16), dimension(10) :: arr3, arr7
    real(kind=16), dimension(2, 10) :: arr4
    real(kind=16), dimension(2, 11) :: arr5
    real(kind=16), dimension(2, 15) :: arr6
    real(kind=16), dimension(22) :: arr8, arr9
    real(kind=16), dimension(380) :: results, expect

    integer :: i, j
    results  = -1.0_16
    do i = 1, 10
       arr3(i) = i*1.0_16
       arr7(i) = i*1.0_16
       do j = 1, 11
          if(mod(j,2) .eq. 0) then
             arr1(i,j) = j*1.0_16
          else
             arr1(i,j) = (11-j)*1.0_16
          endif
          arr2(j) = j*1.0_16
       end do
    end do
    
    data expect /&
   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16, &
   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16, &
   0.0_16, 110.0_16,   0.0_16, 110.0_16,   0.0_16, 110.0_16,   0.0_16, 110.0_16,   0.0_16, 110.0_16, &
   0.0_16, 110.0_16,   0.0_16, 110.0_16,   0.0_16, 110.0_16,   0.0_16, 110.0_16,   0.0_16, 110.0_16, &
   0.0_16, 330.0_16, 330.0_16, 330.0_16, 330.0_16, 330.0_16, 330.0_16, 330.0_16, 330.0_16, 330.0_16, &
 330.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, &
   0.0_16, 220.0_16, 220.0_16, 220.0_16, 220.0_16, 220.0_16, 220.0_16, 220.0_16, 220.0_16, 220.0_16, &
 220.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, &
   0.0_16,   0.0_16,   0.0_16, 220.0_16,   0.0_16, 220.0_16,   0.0_16, 220.0_16,   0.0_16, 220.0_16, &
   0.0_16, 220.0_16,   0.0_16, 220.0_16,   0.0_16, 220.0_16,   0.0_16, 220.0_16,   0.0_16, 220.0_16, &
   0.0_16, 220.0_16,   0.0_16,   0.0_16,   0.0_16, 550.0_16,   0.0_16, 110.0_16,   0.0_16, 440.0_16, &
   0.0_16, 220.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 220.0_16,   0.0_16, 440.0_16, &
   0.0_16, 110.0_16,   0.0_16, 550.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, &
   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, 550.0_16,   0.0_16, 110.0_16,   0.0_16, 440.0_16, &
   0.0_16, 220.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 220.0_16,   0.0_16, 440.0_16, &
   0.0_16, 110.0_16,   0.0_16, 550.0_16,   0.0_16,   0.0_16,   0.0_16, 300.0_16,   0.0_16,  60.0_16, &
   0.0_16, 240.0_16,   0.0_16, 120.0_16,   0.0_16, 180.0_16,   0.0_16, 180.0_16,   0.0_16, 120.0_16, &
   0.0_16, 240.0_16,   0.0_16,  60.0_16,   0.0_16, 300.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, &
   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, 300.0_16,   0.0_16,  60.0_16, &
   0.0_16, 240.0_16,   0.0_16, 120.0_16,   0.0_16, 180.0_16,   0.0_16, 180.0_16,   0.0_16, 120.0_16, &
   0.0_16, 240.0_16,   0.0_16,  60.0_16,   0.0_16, 300.0_16,   0.0_16,   0.0_16,   0.0_16, 550.0_16, &
 110.0_16, 440.0_16, 220.0_16, 330.0_16, 330.0_16, 220.0_16, 440.0_16, 110.0_16, 550.0_16,   0.0_16, &
   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, &
   0.0_16, 300.0_16,  60.0_16, 240.0_16, 120.0_16, 180.0_16, 180.0_16, 120.0_16, 240.0_16,  60.0_16, &
 300.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16,   0.0_16, &
   0.0_16,   0.0_16,   0.0_16, 300.0_16,   0.0_16,  60.0_16,   0.0_16, 240.0_16,   0.0_16, 120.0_16, &
   0.0_16, 180.0_16,   0.0_16, 180.0_16,   0.0_16, 120.0_16,   0.0_16, 240.0_16,   0.0_16,  60.0_16, &
   0.0_16, 300.0_16,   0.0_16,   0.0_16,   0.0_16, 550.0_16,   0.0_16, 110.0_16,   0.0_16, 440.0_16, &
   0.0_16, 220.0_16,   0.0_16, 330.0_16,   0.0_16, 330.0_16,   0.0_16, 220.0_16,   0.0_16, 440.0_16, &
   0.0_16, 110.0_16,   0.0_16, 550.0_16,   0.0_16, 252.0_16,   0.0_16,  58.0_16,   0.0_16, 204.0_16, &
   0.0_16, 106.0_16,   0.0_16, 156.0_16,   0.0_16, 154.0_16,   0.0_16, 108.0_16,   0.0_16, 202.0_16, &
   0.0_16,  60.0_16,   0.0_16, 250.0_16,   1.0_16,   2.0_16,   3.0_16,   4.0_16,   5.0_16,   6.0_16, &
   7.0_16,   8.0_16,   9.0_16,  10.0_16,   1.0_16,   2.0_16,   3.0_16,   4.0_16,   5.0_16,   6.0_16, &
   7.0_16,   8.0_16,   9.0_16,  10.0_16,  10.0_16,  10.0_16,   1.0_16,   2.0_16,   3.0_16,   4.0_16, &
   5.0_16,   6.0_16,   7.0_16,   8.0_16,   9.0_16,  10.0_16,   1.0_16,   2.0_16,   3.0_16,   4.0_16, &
   5.0_16,   6.0_16,   7.0_16,   8.0_16,   9.0_16,  10.0_16,  10.0_16,  10.0_16,   1.0_16,   2.0_16, &
   3.0_16,   4.0_16,   5.0_16,   6.0_16,   7.0_16,   8.0_16,   9.0_16,  10.0_16,   1.0_16,   2.0_16, &
   3.0_16,   4.0_16,   5.0_16,   6.0_16,   7.0_16,   8.0_16,   9.0_16,  10.0_16,  10.0_16,  10.0_16/
!mxv:
  !  arr3=arr1*arr2
    arr4=0.0_16
    arr4(2,:)=matmul(arr1, arr2)
    call assign_result(1,20,arr4,results)

    arr4=0.0_16
    arr4(2,:)=matmul(arr1(:,1:11:2), arr2(1:11:2))
    call assign_result(21,40,arr4,results)

    arr8=0.0_16
    arr8(2:11)=matmul(arr1, arr2)
    call assign_result(41,60,arr8,results)

    arr8=0.0_16
    arr8(2:11)=matmul(arr1(:,2:10:2), arr2(2:10:2))
    call assign_result(61,82,arr8,results)

    arr8=0.0_16
    arr8(2:20:2)=matmul(arr1(:,2:10:2), arr2(2:10:2))
    call assign_result(83,104,arr8,results)
    
    arr5=0.0_16
    arr5(2,:) =matmul(transpose(arr1), arr7)
    call assign_result(105,126,arr5,results)
    
    arr6=0.0_16
    arr6(2,5:15)= matmul(transpose(arr1), arr7)
    call assign_result(127,156,arr6,results)
    
    arr5=0.0_16
    arr5(2,:)=matmul(transpose(arr1(2:10:2,:)), arr7(2:10:2))
    call assign_result(157,178,arr5,results)
    
    arr6=0.0_16
    arr6(2,5:15)=matmul(transpose(arr1(2:10:2,:)), arr7(2:10:2))
    call assign_result(179,208,arr6,results)
    
    arr9=0.0_16
    arr9(2:12)=matmul(transpose(arr1),arr7)
    call assign_result(209,230,arr9,results)
    
    arr9=0.0_16
    arr9(2:12)=matmul(transpose(arr1(2:10:2,:)),arr7(2:10:2))
    call assign_result(231,252,arr9,results)

    arr9=0.0_16
    arr9(2:22:2)=matmul(transpose(arr1(2:10:2,:)),arr7(2:10:2))
    call assign_result(253,274,arr9,results)

!vxm:

  !  arr=arr3*arr1
    
    arr5=0.0_16
    arr5(2,:)= matmul(arr3, arr1)
    call assign_result(275,294,arr5,results)
    
    arr5=0.0_16
    arr5(2,:)=matmul(arr3(1:11:2), arr1(1:11:2,:))
    call assign_result(295,314,arr5,results)
    
    arr8=0.0_16
    arr8(2:12)=matmul(arr3, arr1)
    call assign_result(315,336,arr3,results)
    
    arr8=0.0_16
    arr8(2:12)=matmul(arr3(2:10:2), arr1(2:10:2,:))
    call assign_result(337,358,arr3,results)
    
    arr8=0.0_16
    arr8(2:22:2)=matmul(arr3(2:10:2), arr1(2:10:2,:))
    call assign_result(359,380,arr3,results)
    
    call checkr16(results,expect,380)
end program

subroutine assign_result(s_idx, e_idx , arr, rslt)
  integer :: s_idx, e_idx
  REAL*16, dimension(1:e_idx-s_idx+1) :: arr
  REAL*16, dimension(e_idx) :: rslt


  rslt(s_idx:e_idx) = arr

end subroutine

